#!/usr/bin/ruby
# -*- ruby -*-
#
# http://programmingpraxis.com/2013/05/07/three-list-exercises/

require 'test/unit'
require 'set'

class Array
  def remove_nth(n)
    return each_index.inject([]) do |acc, i|
      acc << self[i] if i % n != 0
      acc
    end
  end
  
  def unique
    t = Set.new

    return inject([]) do |acc, el|
      unless t.include?(el)
        acc << el
        t << el
      end

      acc
    end
  end

  def half
    return each_index.inject([[], []]) do |acc, i|
      ((i < self.size / 2) ? acc.first : acc.last) << self[i]

      acc
    end
  end
end

class ArrayTest < Test::Unit::TestCase
  def test_remove_nth
    assert_equal [], [].remove_nth(0)
    assert_equal [], [].remove_nth(1)
    assert_equal [], %w{a}.remove_nth(1)
    assert_equal [], %w{a}.remove_nth(1)
    assert_equal [], %w{a b c}.remove_nth(1)
    assert_equal %w{b d}, %w{a b c d}.remove_nth(2)
    assert_equal %w{b c e f}, %w{a b c d e f g}.remove_nth(3)
  end

  def test_unique
    assert_equal [], [].unique
    assert_equal %w{1}, %w{1}.unique
    assert_equal %w{1 2 3 4 5}, %w{1 2 3 4 5}.unique
    assert_equal %w{1 2 3 4 5}, %w{1 1 2 3 4 5}.unique
    assert_equal %w{1 2 3 4 5}, %w{1 2 1 3 1 4 1 5 1}.unique
    assert_equal %w{1 2 3 4 5}, %w{1 2 2 3 3 3 4 4 4 4 5 5 5 5 5}.unique
  end

  def test_half
    assert_equal [[], []], [].half
    assert_equal [[], %w{1}], %w{1}.half
    assert_equal [%w{1}, %w{2}], %w{1 2}.half
    assert_equal [%w{1 2}, %w{3 4 5}], %w{1 2 3 4 5}.half
    assert_equal [%w{1 2}, %w{3 4 5}], %w{1 2 3 4 5}.half
    assert_equal [%w{1 2 3}, %w{4 5 6}], %w{1 2 3 4 5 6}.half
  end
end
